/**
 * 创建弹出框
 */
import ElementPlus from "element-plus";
import Dialog from "../components/Dialog.vue";
import { createApp, h, nextTick } from "vue";
import zhCn from "element-plus/es/locale/lang/zh-cn";

interface Props {
  location: {
    x: number;
    y: number;
    bottom: number;
    width: number;
    height: number;
  };
  direction?: "top" | "bottom" | "left" | "right";
  props: Record<string, any>;
  close: () => void;
  parentInstance: any;
  type?: "dialog" | "popover";
  options?: Record<string, any>; // dialog | popover的组件参数
}
import type { Component } from "vue";

/**
 * start 多层弹窗管理
 */
let zIndex = 1999;
let dialogList: any = [];
const removeLastPop = () => {
  console.log(dialogList);
  if (dialogList.length >= 1) {
    const lastDialog = dialogList.pop();
    lastDialog.close();
  }
};

/**
 * end多层弹窗管理
 */

const maskDomHandler = () => {
  const mask = document.createElement("div");
  const eventStopHandler = (e: MouseEvent) => {
    e.stopPropagation();
    removeLastPop();
  };

  const appendMask = (options: any) => {
    const { type } = options;
    const zIndexCopy = zIndex;
    mask.style.cssText = `
      position:fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: ${zIndex++};
      background: ${type === "dialog" ? "rgba(0, 0, 0, 0.50)" : "transparent"};
    `;
    document.body.appendChild(mask);
    mask.addEventListener("click", eventStopHandler);
    return zIndexCopy;
  };
  return {
    appendMask,
    removeMask: () => {
      document.body.removeChild(mask);
      mask.removeEventListener("click", eventStopHandler);
    }
  };
};

const positionHandler = (location: any, div: any, direction: any) => {
  let { x, y, height, width } = location; // width
  const { width: widthTarget, height: heightTarget } = div.getBoundingClientRect();
  const viewWidth = document.documentElement.clientWidth;
  const viewHeight = document.documentElement.clientHeight;
  if (direction === "left") {
    x = x - widthTarget + width;
  }

  let top = y + height; // 优先目标底部
  let left = x; // 优先目标左边

  // 判断垂直方向
  if (viewHeight - top >= heightTarget) {
    top = top;
  } else if (viewHeight - top < heightTarget) {
    if (y >= heightTarget) {
      top = y - heightTarget;
    } else {
      top = (viewHeight - heightTarget) / 2; // 目标中间
    }
  }

  // 水平方向
  if (viewWidth - x >= widthTarget) {
    left = x;
  } else if (viewWidth - x < widthTarget) {
    if (x >= widthTarget) {
      left = x - widthTarget;
    } else {
      left = (viewWidth - widthTarget) / 2; // 目标中间
    }
  }
  // if (viewWidth - x < widthTarget) {
  //   left = x - widthTarget;
  // }

  // if (viewHeight - top < heightTarget) {
  //   top = y - heightTarget;
  // }
  if (direction === "top") {
    top = y;
  }
  return {
    top,
    left,
    width
  };
};

export const popUp = (params: Props, component?: Component) => {
  const { location, props, close, direction, parentInstance, type, options } = params;
  const { removeMask, appendMask } = maskDomHandler();
  const div = document.createElement("div");

  div.addEventListener("click", e => {
    e.stopPropagation();
  });

  // const handleWindowClick = (e: MouseEvent) => {
  //   if (!e.isTrusted) return;
  //   if (div && !div.contains(e.target as Node)) {
  //     removeLastPop();
  //   }
  // };
  const remove = () => {
    app.unmount();
    div.remove();
    removeMask();
    close();
    // window.removeEventListener("click", handleWindowClick);
  };

  // window.addEventListener("click", handleWindowClick);

  const app = createApp({
    setup() {
      return () =>
        type === "dialog"
          ? h(
              Dialog,
              { ...options, onClose: removeLastPop },
              {
                ...(options as any).slots
              }
            )
          : h(component as Component, { ...props, onClose: removeLastPop });
    }
  });
  // 将父组件的 provide 上下文传递给弹框组件
  app._context.provides = parentInstance?.provides;
  app._context.provides["popClose"] = removeLastPop;
  // 字典
  app.config.globalProperties.$dict = window.staticConfig.dictionary;

  app
    .use(ElementPlus, {
      locale: zhCn
    })
    .mount(div);

  div.style.cssText = `
      position:fixed;
      opacity: 0;
    `;

  document.body.appendChild(div);
  const zIndexCopy = appendMask({ type });
  dialogList.push({
    id: zIndexCopy,
    close: remove
  });

  nextTick(() => {
    if (type === "dialog") {
      div.style.cssText = `
      position:fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
      width: fit-content;
      height: fit-content;
      z-index: ${zIndex++};
      opacity: 1;
      transition: opacity 0.2s;
    `;
    } else {
      const { top, left, width } = positionHandler(location, div, direction);
      div.style.cssText = `
          position:fixed;
          width: ${width}px;
          top: ${top}px;
          left: ${left}px;
          z-index: ${zIndex++};
          opacity: 1;
          transition: opacity 0.2s;
        `;
    }
  });

  return { removeLastPop };
};
